package gdf

import (
	"fmt"
	"gitee.com/liumou_site/logger"
	"net/http"
)

// New 创建并初始化一个新的DownloadThreadController实例。
// 该函数返回一个指向DownloadThreadController的指针，该实例的Exit通道和Save属性已被初始化。
// Exit通道用于线程间通信，以控制下载线程的退出。
// Save属性表示是否保存下载的文件，默认为true。
func New() *DownloadThreadController {
	d := new(DownloadThreadController)
	d.Exit = make(chan int)
	d.Save = true
	return d
}

// NewSingleness 创建并初始化一个Singleness对象。
// 参数:
//
//	url - 文件的URL地址。
//	filename - 保存文件时使用的文件名。
//
// 返回值:
//
//	*Singleness - 初始化后的Singleness对象指针。
//	error - 如果创建过程中发生错误，返回该错误。
func NewSingleness(url, filename string) (*Singleness, error) {
	// 创建一个新的Singleness对象。
	d := new(Singleness)
	// 设置文件的URL地址。
	d.FileUrl = url
	// 设置保存文件时使用的文件名。
	d.FileName = filename
	// 初始化文件大小为0。
	d.FileSize = 0
	// 默认将文件保存到磁盘。
	d.SaveToDisk = true
	// 设置文件的最大大小限制为500。
	d.MaxSize = 500

	// 创建一个GET请求到指定的URL地址。
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		// 如果创建请求时发生错误，记录错误日志并返回。
		logger.Error(err)
		return d, err
	}

	// 为请求设置头部信息。
	d.Request = setHeader(req)

	// 返回初始化完成的Singleness对象。
	return d, nil
}

// NewThread 创建一个新的Thread实例。
// 它通过给定的URL初始化Thread对象，并设置初始配置，如线程数和文件URL。
// 参数:
//
//	url - 需要下载的文件的URL。
//
// 返回值:
//
//	*Thread - 初始化后的Thread实例。
func NewThread(url string) *Thread {
	// 创建一个新的Thread实例
	t := new(Thread)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		logger.Error(err)
		return t
	}
	t.Request = setHeader(req)
	// 初始化退出通道，用于线程之间的通信，以优雅地退出线程
	t.Exit = false

	// 设置默认的线程数为5，用于并发下载
	t.ThreadCount = 5

	// 设置文件的URL
	t.FileUrl = url

	// 根据URL检查是否支持断点续传，并设置相应的标志
	t.SuppressRange = GetRangeStatus(url)

	// 默认情况下，不将文件保存到磁盘
	t.SaveToDisk = false

	// 如果不支持断点续传，则将线程数重置为1，因为无需并发下载
	if !t.SuppressRange {
		t.ThreadCount = 5
	}
	// 设置默认的下载文件夹
	t.DownloadFolder = "./"
	// 设置默认的下载文件名
	t.DownloadFileName = "default"
	// 设置默认请求头，以指示下载文件的范围
	t.Request.Header.Set("Range", fmt.Sprintf("bytes=0-%d", t.ContentSize-1))
	// 调用getFileSize方法获取文件的大小
	t.ContentSize, t.ContentLength, t.Error = GetContentLength(t.FileUrl, t.Debug)
	t.Length = t.ContentLength / int64(t.ThreadCount)
	// 设置内存
	t.MemFree = 50
	// 返回初始化后的Thread实例
	return t
}
